package com.demo.commons;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import redis.clients.jedis.JedisPool;

import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

public class RedisTemplate extends RedisCommond {

    public RedisTemplate(JedisPool jedisPool) {
        super(jedisPool);
    }

    /**
     * 获取一个值
     *
     */
    public String get(String key) {
        return run(jedis -> jedis.get(key));
    }

    /**
     * 获取一个值（json字符串），并转换成对象
     *
     */
    public <T> T get(String key, Class<T> clazz) {
        return run(jedis -> JSONObject.parseObject(jedis.get(key), clazz));
    }

    /**
     * 获取一个值（json数组），并转换成对象集合
     *
     */
    public <T> List<T> getList(String key, Class<T> clazz) {
        return run(jedis -> JSONArray.parseArray(jedis.get(key), clazz));
    }

    /**
     * 设置一个值
     *
     */
    public void set(String key, String value) {
        run(jedis -> jedis.set(key, value));
    }

    /**
     * 设置一个值,以json格式储存
     *
     */
    public void set(String key, Object value) {
        run(jedis -> jedis.set(key, JSONObject.toJSONString(value)));
    }

    /**
     * 设置值带过期时间
     *
     */
    public void setEx(String key, String value, int seconds) {
        run(jedis -> jedis.setex(key, seconds, value));
    }

    /**
     * 删除key
     *
     */
    public void del(String key) {
        run(jedis -> jedis.del(key));
    }

    /**
     * 批量删除key
     *
     */
    public void del(String... keys) {
        run(jedis -> jedis.del(keys));
    }

    /**
     * 设置值带过期时间
     *
     */
    public void setEx(String key, Object value, int seconds) {
        run(jedis -> jedis.setex(key, seconds, JSONObject.toJSONString(value)));
    }

    /**
     * 按照模糊查询Key
     *
     */
    public Set<String> keys(String pattern) {
        return run(jedis -> jedis.keys(pattern));
    }

    /**
     * HSet新增
     *
     */
    public void hSet(String key, String field, String value) {
        run(jedis -> jedis.hset(key, field, value));
    }

    /**
     * 设置hash里面一个字段的值
     *
     */
    public void hSet(String key, Map<String, String> fields) {
        run(jedis -> {
            fields.entrySet().forEach((entry) -> jedis.hset(key, entry.getKey(), entry.getValue()));
            return null;
        });
    }

    /**
     * hExists 判断给定域是否存在于哈希集中
     *
     */
    public Boolean hExists(String key, String fileld) {
        return run(jedis -> jedis.hexists(key, fileld));
    }

    /**
     * HINCRBY 将哈希集中指定域的值增加给定的数字
     *
     */
    public Long hIncrby(String key, String fileld, Long value) {
        return run(jedis -> jedis.hincrBy(key, fileld, value));
    }

    /**
     * hIncrbyFloat 将哈希集中指定域的值增加给定的浮点数
     *
     */
    public Double hIncrbyFloat(String key, String fileld, Double value) {
        return run(jedis -> jedis.hincrByFloat(key, fileld, value));
    }

    /**
     * hLen 将哈希集中指定域的值增加给定的浮点数
     *
     */
    public Long hLen(String key) {
        return run(jedis -> jedis.hlen(key));
    }

    /**
     * hKeys 获取hash的所有字段
     *
     */
    public Set<String> hKeys(String key) {
        return run(jedis -> jedis.hkeys(key));
    }

    /**
     * HDEL  获取hash的所有字段
     *
     */
    public Long hDel(String key, String... field) {
        return run(jedis -> jedis.hdel(key, field));
    }

    /**
     * HGETALL  从哈希集中读取全部的域和值
     *
     */
    public Map<String, String> hGetAll(String key) {
        return run(jedis -> jedis.hgetAll(key));
    }

    /**
     * HGET 读取哈希域的的值
     *
     */
    public String hGet(String key, String field) {
        return run(jedis -> jedis.hget(key, field));
    }


    /**
     * HVALS  获得hash的所有值
     *
     */
    public List<String> hVals(String key) {
        return run(jedis -> jedis.hvals(key));
    }

    /**
     * HVALS  设置hash的一个字段，只有当这个字段不存在时有效
     *
     */
    public Long hSetNx(String key, String field, String value) {
        return run(jedis -> jedis.hsetnx(key, field, value));
    }

    /**
     * HMGET  获取hash里面指定字段的值
     *
     */
    public List<String> hMget(String key, String... fields) {
        return run(jedis -> jedis.hmget(key, fields));
    }

    /**
     * HMSET  设置hash字段值
     */
    public String hMset(String key, Map<String, String> fields) {
        return run(jedis -> jedis.hmset(key, fields));
    }

    public void expire(String key, int times) {
        run(jedis -> jedis.expire(key, times));
    }

    public Boolean exist(String key) {
        return run(jedis -> jedis.exists(key));
    }

    /**
     * 从尾部取出一个元素，并删除
     *
     */
    public String rpop(String key) {
        return run(jedis -> jedis.rpop(key));
    }

    public Set<String> rpop(String key, long count) {
        return run(jedis -> {
            Set<String> set = new HashSet<>();
            while (set.size() < count) {
                String value = jedis.rpop(key);
                if (value == null) break;
                set.add(value);
            }
            return set;
        });
    }

    /**
     * 从尾部加入元素
     *
     */
    public Long rpush(String key, String... values) {
        return run(jedis -> jedis.rpush(key, values));
    }

    /**
     * 从首部取出一个元素，并删除
     */
    public String lpop(String key) {
        return run(jedis -> jedis.lpop(key));
    }


    public Set<String> lpop(String key, long count) {
        return run(jedis -> {
            Set<String> set = new HashSet<>();
            while (set.size() < count) {
                String value = jedis.lpop(key);
                if (value == null) break;
                set.add(value);
            }
            return set;
        });
    }

    /**
     * 从首部加入元素
     */
    public Long lpush(String key, String... values) {
        return run(jedis -> jedis.lpush(key, values));
    }

    /**
     * 添加set元素
     */
    public Long sadd(String key, String... values) {
        return run(jedis -> jedis.sadd(key, values));
    }

    /**
     * (set)取出一个随机元素，并删除
     */
    public String spop(String key) {
        return run(jedis -> jedis.spop(key));
    }

    /**
     * (set)取出多个随机元素，并删除
     *
     */
    public Set<String> spop(String key, long count) {
        return run(jedis -> jedis.spop(key, count));
    }

    public Long scard(String key) {
        return run(jedis -> jedis.scard(key));
    }
}
